using CoreManager.AI.Models;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;

namespace CoreManager.AI.Services;

/// <summary>
/// 基于内存缓存的会话历史服务
/// </summary>
public class MemorySessionHistoryService : ISessionHistoryService
{
    private readonly IMemoryCache _cache;
    private readonly ILogger<MemorySessionHistoryService> _logger;
    private const string SESSION_KEY_PREFIX = "session_";
    private const string ALL_SESSIONS_KEY = "all_sessions";
    private static readonly TimeSpan DefaultExpiration = TimeSpan.FromHours(24);

    public MemorySessionHistoryService(
        IMemoryCache cache,
        ILogger<MemorySessionHistoryService> logger)
    {
        _cache = cache;
        _logger = logger;
    }

    /// <summary>
    /// 获取会话历史
    /// </summary>
    public async Task<SessionHistory> GetSessionHistoryAsync(string sessionId)
    {
        var key = GetSessionKey(sessionId);
        
        if (_cache.TryGetValue(key, out SessionHistory? history) && history != null)
        {
            _logger.LogDebug("从缓存获取会话历史: {SessionId}, 消息数: {Count}", sessionId, history.Messages.Count);
            return history;
        }

        // 创建新会话
        var newHistory = new SessionHistory
        {
            SessionId = sessionId,
            CreatedAt = DateTime.UtcNow,
            LastActivityAt = DateTime.UtcNow
        };

        await SaveSessionHistoryAsync(newHistory);
        
        _logger.LogInformation("创建新会话: {SessionId}", sessionId);
        return newHistory;
    }

    /// <summary>
    /// 保存或更新会话历史
    /// </summary>
    public Task SaveSessionHistoryAsync(SessionHistory sessionHistory)
    {
        var key = GetSessionKey(sessionHistory.SessionId);
        
        // 更新最后活动时间
        sessionHistory.LastActivityAt = DateTime.UtcNow;

        // 使用滑动过期：24小时内无活动则过期
        var cacheOptions = new MemoryCacheEntryOptions()
            .SetSlidingExpiration(DefaultExpiration)
            .RegisterPostEvictionCallback((evictedKey, value, reason, state) =>
            {
                _logger.LogInformation("会话已从缓存中移除: {Key}, 原因: {Reason}", evictedKey, reason);
            });

        _cache.Set(key, sessionHistory, cacheOptions);
        
        // 更新会话列表
        UpdateSessionList(sessionHistory.SessionId);

        _logger.LogDebug("保存会话历史: {SessionId}, 消息数: {Count}", 
            sessionHistory.SessionId, sessionHistory.Messages.Count);

        return Task.CompletedTask;
    }

    /// <summary>
    /// 添加消息到会话
    /// </summary>
    public async Task AddMessageAsync(string sessionId, ChatMessage message)
    {
        var history = await GetSessionHistoryAsync(sessionId);
        
        history.Messages.Add(message);
        
        // 如果是第一条用户消息且没有标题，可以设置标题
        if (history.Messages.Count == 1 && 
            message.Role == ChatRole.User && 
            string.IsNullOrEmpty(history.Title))
        {
            // 截取前30个字符作为标题
            history.Title = message.Content.Length > 30 
                ? message.Content.Substring(0, 30) + "..." 
                : message.Content;
        }

        await SaveSessionHistoryAsync(history);
        
        _logger.LogDebug("添加消息到会话: {SessionId}, 角色: {Role}", sessionId, message.Role);
    }

    /// <summary>
    /// 清除会话历史
    /// </summary>
    public async Task ClearSessionHistoryAsync(string sessionId)
    {
        var history = await GetSessionHistoryAsync(sessionId);
        history.Messages.Clear();
        history.LastActivityAt = DateTime.UtcNow;
        
        await SaveSessionHistoryAsync(history);
        
        _logger.LogInformation("清除会话历史: {SessionId}", sessionId);
    }

    /// <summary>
    /// 获取所有会话列表
    /// </summary>
    public Task<List<SessionHistory>> GetAllSessionsAsync(int? limit = null)
    {
        var sessionIds = GetSessionList();
        var sessions = new List<SessionHistory>();

        foreach (var sessionId in sessionIds)
        {
            var key = GetSessionKey(sessionId);
            if (_cache.TryGetValue(key, out SessionHistory? history) && history != null)
            {
                sessions.Add(history);
            }
        }

        // 按最后活动时间倒序排序
        var orderedSessions = sessions
            .OrderByDescending(s => s.LastActivityAt)
            .AsEnumerable();

        if (limit.HasValue)
        {
            orderedSessions = orderedSessions.Take(limit.Value);
        }

        return Task.FromResult(orderedSessions.ToList());
    }

    /// <summary>
    /// 删除会话
    /// </summary>
    public Task DeleteSessionAsync(string sessionId)
    {
        var key = GetSessionKey(sessionId);
        _cache.Remove(key);
        
        // 从会话列表中移除
        RemoveFromSessionList(sessionId);
        
        _logger.LogInformation("删除会话: {SessionId}", sessionId);
        
        return Task.CompletedTask;
    }

    /// <summary>
    /// 清理过期会话
    /// </summary>
    public async Task<int> CleanupExpiredSessionsAsync(int expirationHours = 24)
    {
        var expirationTime = DateTime.UtcNow.AddHours(-expirationHours);
        var sessions = await GetAllSessionsAsync();
        
        var expiredSessions = sessions
            .Where(s => s.LastActivityAt < expirationTime)
            .ToList();

        foreach (var session in expiredSessions)
        {
            await DeleteSessionAsync(session.SessionId);
        }

        if (expiredSessions.Count > 0)
        {
            _logger.LogInformation("清理过期会话: {Count} 个", expiredSessions.Count);
        }

        return expiredSessions.Count;
    }

    #region Private Methods

    private static string GetSessionKey(string sessionId)
    {
        return $"{SESSION_KEY_PREFIX}{sessionId}";
    }

    private List<string> GetSessionList()
    {
        if (_cache.TryGetValue(ALL_SESSIONS_KEY, out List<string>? list) && list != null)
        {
            return list;
        }

        return new List<string>();
    }

    private void UpdateSessionList(string sessionId)
    {
        var list = GetSessionList();
        
        if (!list.Contains(sessionId))
        {
            list.Add(sessionId);
            
            // 永久保存会话列表
            _cache.Set(ALL_SESSIONS_KEY, list, new MemoryCacheEntryOptions
            {
                Priority = CacheItemPriority.NeverRemove
            });
        }
    }

    private void RemoveFromSessionList(string sessionId)
    {
        var list = GetSessionList();
        
        if (list.Remove(sessionId))
        {
            _cache.Set(ALL_SESSIONS_KEY, list, new MemoryCacheEntryOptions
            {
                Priority = CacheItemPriority.NeverRemove
            });
        }
    }

    #endregion
}

